import { ref, unref, type Ref } from "vue";
import type { IAdminListItem, IAdminListRes } from "@/request/UmsAdminController/index"



/**
 * 
 * @param api 请求表格data的api
 * @param queryParams 请求表格data的可选参数
 * @returns 返回操作表格data 和 操作表格data的方法
 */
interface IRes {
  list: any;
  pageNum: number;
  pageSize: number;
  total: number;
  totalPage: number;
}

// 使用IRes约束R的类型，使其可以R["list"]取到
function useTable<P, R extends IRes>(api: (data?: P) => Promise<R>, queryParams?: P) {
  // const tableData: Ref<IAdminListItem[]> = ref([]);
  // 所有的api的返回值 都是R，都有一个list字段。但每个list字段都不同
  const tableData: Ref<R["list"]> = ref([]);


  // 分页器：写成响应式，不然样式不会变
  const pagination = ref({
    pageNum: 1,
    pageSize: 5,
    total: 0,
    totalPage: 0,
  })

  // 请求获取用户信息列表
  async function getTableData() {


    let normalQueryParams = {} as P;

    // 【B】当传入的 queryParams 为undefined时，设为{} 并定义为P类型--->为了响应式传值， 传进来的queryParams是一个Ref类型，因此需要将其做一层深拷贝，创建一个 normalQueryParam 参数。---> C
    // if (typeof queryParams === "undefined") {
    //   // queryParams = {} as P;
    // } 


    // 【C】 如果不限定queryParams类型，那它可能是undefined，导致类型不匹配
    // 将queryParams限定为object类型，
    // 或者queryParams不为undefined类型，
    // if (typeof queryParams !== "undefined") {

    if (typeof queryParams === "object") {
      // 如果queryParams 非空，那就将内部的响应式数据Ref转为正常值。
      for (let key in queryParams) {
        normalQueryParams[key] = unref(queryParams[key]);
      }
    }


    // 【A】if (typeof queryParams === "object") {
    // queryParams是P类型，如果它是对象，就会被...扩展，那么api接收的参数也变为P类型。所以不会报错。但是这么写会有bug，因为不一定会传queryParams参数。---> B
    let result = await api({
      pageNum: pagination.value.pageNum,
      pageSize: pagination.value.pageSize,
      // ...queryParams,
      ...normalQueryParams,
    });


    let { pageNum, pageSize, total, totalPage, list } = result;
    tableData.value = list;
    pagination.value = { pageNum, pageSize, total, totalPage };
  }
  getTableData();



  const handleSizeChange = (val: number) => {
    // console.log(`${val} items per page`)

    pagination.value.pageSize = val;
    getTableData();
  }
  const handleCurrentChange = (val: number) => {
    // console.log(`current page: ${val}`)
    pagination.value.pageNum = val;
    getTableData();
  }

  return { pagination, tableData, handleSizeChange, handleCurrentChange, getTableData }
}

export default useTable;


// 封装自定义可复用的配置表格的hook
// 抽离出同样功能的代码，封装为一个函数，在页面里调用该函数即可实现相同的功能。
// 0 导出一个自定义的hook函数
// 1 需要引入库
// 2 请求的方法不同---传入api
// 3 传入的参数不同---传入参数
// 4 hook函数返回在页面需要用到的东西

